import {
  useCallback,
  useState,
  useRef,
  useMemo,
  forwardRef,
  useImperativeHandle,
  useEffect,
} from 'react';
import { Upload, Image } from '@douyinfe/semi-ui';
import { AUDIO_UPLOAD_CONFIG, formatFileSize } from './constants';
import styles from './index.module.scss';
import { ICON_PATHS } from '@/assets/images/constants';
import request from '@/utils/request';
import axios from 'axios';

/**
 * 通用音频上传组件
 * @param {Object} props
 * @param {string} props.title - 上传标题
 * @param {string} props.uploadKey - 上传键值，用于区分不同上传实例
 * @param {string} props.subtitle - 副标题
 * @param {string} props.currentMenuKey - 当前菜单键，用于Redux存储路径
 * @param {Function} props.onUpload - 上传成功回调函数
 * @param {Function} props.onHistoryClick - 历史文件点击回调
 * @param {Object} props.audioObj - 当前已上传的音频对象
 * @param {Function} props.onAudioRemove - 音频删除回调
 * @param {string} props.action - 上传接口地址
 * @param {boolean} props.showAudioPlayer - 是否显示音频播放器
 * @param {Object} props.customConfig - 自定义上传配置
 */
const AudioUploadComponent = forwardRef(
  (
    {
      title,
      uploadKey,
      subtitle = '支持MP3、WAV、OGG等格式',
      currentMenuKey,
      onUpload,
      onHistoryClick,
      audioObj = {},
      onAudioRemove,
      action = '/dk/v1/fileTransfer/uploader',
      showAudioPlayer = true,
      customConfig = {},
    },
    ref
  ) => {
    const [uploading, setUploading] = useState(false);
    const [error, setError] = useState('');
    const [uploadProgress, setUploadProgress] = useState(0);
    const [currentUploadFileName, setCurrentUploadFileName] = useState(''); // 添加当前上传文件名状态
    const xhrRef = useRef(null); // 添加xhr引用,取消上传
    const isUploadingRef = useRef(false); // 使用ref跟踪上传状态，避免闭包问题
    const progressUpdateRef = useRef(null); // 添加一个ref来跟踪进度更新定时器
    const fileInputRef = useRef(null); // 添加文件输入引用

    // 生成唯一的音频键
    const audioKey = `${currentMenuKey}_${uploadKey}`;
    const hasAudio = audioObj[audioKey];
    const uploadClassName = `${styles.uploadSection} ${error ? styles.hasError : ''}`;
    const smoothProgressRef = useRef(0);

    // 合并默认配置和自定义配置
    const uploadConfig = useMemo(
      () => ({
        ...AUDIO_UPLOAD_CONFIG,
        action,
        ...customConfig,
        beforeUpload: options => {
          const file = options.file;
          console.log('beforeUpload file:', file);

          // 执行默认的beforeUpload检查
          const defaultCheck = AUDIO_UPLOAD_CONFIG.beforeUpload(options);
          if (defaultCheck !== true) {
            return defaultCheck;
          }

          // 执行自定义beforeUpload检查（如果有）
          if (typeof customConfig.beforeUpload === 'function') {
            return customConfig.beforeUpload(options);
          }

          setUploading(true);
          isUploadingRef.current = true;
          setError('');
          setUploadProgress(1);
          setCurrentUploadFileName(file.name);
          console.log('Starting upload:', file.name); // 添加日志以便调试
          return true;
        },
      }),
      [action, customConfig]
    );

    const handleCustomRequest = useCallback(
      async options => {
        console.log('handleCustomRequest options:', options);
        if (options.uploadKey && uploadConfig.beforeUpload(options)) {
          console.log('shoudong');
        }

        const { onProgress, onError, onSuccess, file } = options;

        // 获取文件大小（字节）
        const fileSize = file?.fileInstance?.size || 0;
        // 计算文件大小类别（小文件 < 1MB, 中文件 < 10MB, 大文件 >= 10MB）
        const fileSizeCategory =
          fileSize < 1024 * 1024 ? 'small' : fileSize < 10 * 1024 * 1024 ? 'medium' : 'large';

        try {
          // 如果是本地预览模式，直接处理文件
          if (uploadConfig.mode === 'local') {
            // 模拟上传进度
            const simulateProgress = () => {
              return new Promise(resolve => {
                let progress = 0;
                // 清除之前可能存在的定时器
                if (progressUpdateRef.current) {
                  clearInterval(progressUpdateRef.current);
                }

                // 根据文件大小设置基本参数
                const paramsBySize = {
                  small: {
                    totalDuration: 1500, // 小文件总上传时间约1.5秒
                    interval: 150, // 更新间隔
                    initialSpeedFactor: 1.5, // 初始阶段速度因子
                    finalSpeedFactor: 0.8, // 末尾阶段速度因子
                  },
                  medium: {
                    totalDuration: 3500, // 中文件总上传时间约3.5秒
                    interval: 200, // 更新间隔
                    initialSpeedFactor: 1.2, // 初始阶段速度因子
                    finalSpeedFactor: 0.6, // 末尾阶段速度因子
                  },
                  large: {
                    totalDuration: 8000, // 大文件总上传时间约8秒
                    interval: 250, // 更新间隔
                    initialSpeedFactor: 1.0, // 初始阶段速度因子
                    finalSpeedFactor: 0.4, // 末尾阶段速度因子
                  },
                };
                const { interval, initialSpeedFactor, finalSpeedFactor } =
                  paramsBySize[fileSizeCategory];

                // 生成基于文件大小和当前进度的上传速度
                const getRandomSpeed = currentProgress => {
                  // 计算速度衰减因子（随着进度增加，速度逐渐减慢）
                  const decayFactor = 1 - (currentProgress / 100) * (1 - finalSpeedFactor);

                  // 初始阶段速度较快
                  if (currentProgress < 30) {
                    return Math.random() * 8 * initialSpeedFactor * decayFactor + 5;
                  }
                  // 中间阶段速度波动较大
                  else if (currentProgress < 80) {
                    // 大文件更可能出现网络波动
                    const Probability = fileSizeCategory === 'large' ? 0.2 : 0.1;
                    if (Math.random() < Probability) {
                      // 大文件可能有更明显的速度下降
                      const slowdownFactor = fileSizeCategory === 'large' ? 0.5 : 1;
                      return Math.random() * 2 * slowdownFactor + 1;
                    }
                    return Math.random() * 6 * decayFactor + 3;
                  }
                  // 接近完成阶段速度变慢
                  else {
                    // 大文件在最后阶段可能需要更长时间
                    const finalDelayFactor = fileSizeCategory === 'large' ? 1.5 : 1;
                    return Math.random() * 3 * finalDelayFactor * decayFactor + 0.5;
                  }
                };

                progressUpdateRef.current = setInterval(() => {
                  // 检查是否已取消上传
                  if (!isUploadingRef.current) {
                    clearInterval(progressUpdateRef.current);
                    progressUpdateRef.current = null;
                    resolve();
                    return;
                  }

                  // 获取基于当前进度的随机增长值
                  const increment = getRandomSpeed(progress);
                  progress += increment;

                  // 确保进度不超过99%（为最后的完成阶段预留）
                  if (progress > 99) {
                    progress = 99;
                  }

                  console.log('Progress update:', progress); // 添加日志以便调试
                  setUploadProgress(Math.round(progress));
                  // 当进度接近100%时，模拟最后的完成处理
                  if (progress >= 99) {
                    // 模拟服务器处理时间
                    // 根据文件大小调整最后的服务器处理时间
                    const finalProcessingTime = fileSizeCategory === 'large' ? 1200 : 800;
                    setTimeout(() => {
                      if (isUploadingRef.current) {
                        setUploadProgress(100);
                        clearInterval(progressUpdateRef.current);
                        progressUpdateRef.current = null;
                        resolve();
                      }
                    }, finalProcessingTime); // 模拟最后的服务器处理延迟
                  }
                }, interval);
              });
            };

            await simulateProgress();

            // 处理本地文件
            if (typeof onUpload === 'function' && isUploadingRef.current) {
              // 确保上传未被取消
              await onUpload({ file, uploadKey });
            }
            setUploading(false);
          } else {
            // 创建FormData对象
            const formData = new FormData();
            formData.append('file', file.fileInstance);
            formData.append('fileName', file.name);

            // 如果有自定义表单数据，添加到FormData中
            if (customConfig.formData) {
              Object.entries(customConfig.formData).forEach(([key, value]) => {
                formData.append(key, value);
              });
            }

            // 创建取消令牌，用于取消上传
            // console.log(axios.CancelToken);
            
            const source = request.createCancelSource();
            xhrRef.current = source; // 保存取消令牌引用

            // 使用Axios发送请求并监听进度
            const data = await request.post(action, formData, {
              cancelToken: source.token,
              headers: {
                'Content-Type': 'multipart/form-data',
              },
              onUploadProgress: event => {
                
                console.log('非本地模式', event);
                if (event.lengthComputable && isUploadingRef.current) {
                  const actualProgress = Math.round((event.loaded / event.total) * 100);
                  console.log('Server progress update:', actualProgress); // 添加日志以便调试

                  // 根据文件大小调整平滑进度的更新参数
                  let smoothingFactor = 0.3;
                  let maxIncrement = 10;

                  if (fileSizeCategory === 'small') {
                    // 小文件可以更快地更新到实际进度
                    smoothingFactor = 0.5;
                    maxIncrement = 15;
                  } else if (fileSizeCategory === 'large') {
                    // 大文件需要更平滑的过渡
                    smoothingFactor = 0.2;
                    maxIncrement = 8;
                  }

                  // 平滑进度更新
                  if (actualProgress > smoothProgressRef.current) {
                    // 根据实际进度与平滑进度的差距动态调整更新速度
                    const diff = actualProgress - smoothProgressRef.current;
                    const increment =
                      diff > 5
                        ? Math.min(diff * smoothingFactor, maxIncrement)
                        : diff * smoothingFactor + 0.5;
                    smoothProgressRef.current += increment;

                    // 确保平滑进度不超过实际进度
                    if (smoothProgressRef.current > actualProgress) {
                      smoothProgressRef.current = actualProgress;
                    }

                    setUploadProgress(Math.round(smoothProgressRef.current));
                  } else if (actualProgress === 100) {
                    setUploadProgress(100);
                  }
                }
              },
            });

            // 调用上传成功回调
            if (typeof onUpload === 'function' && isUploadingRef.current) {
              await onUpload({
                file,
                uploadKey,
                serverData: data.data,
              });
            }
          }
        } catch (err) {
          console.error('音频上传失败:', err);
          if (axios.isCancel(error)) {
            console.log('Upload canceled:', error.message);
          } else {
            if (err.message !== '上传已取消' && !axios.isCancel(err)) {
              setError(err.message || '上传失败，请重试');
            }
          }
        } finally {
          // 清除进度更新定时器
          if (progressUpdateRef.current) {
            clearInterval(progressUpdateRef.current);
            progressUpdateRef.current = null;
          }
          // 只有在上传没有被取消的情况下才更新状态
          if (isUploadingRef.current) {
            setUploading(false);
            isUploadingRef.current = false;
          }
        }
      },
      [onUpload, uploadKey, action, uploadConfig.mode, customConfig.formData]
    );

    const handleHistoryClickWrapper = useCallback(
      e => {
        e.stopPropagation();
        if (typeof onHistoryClick === 'function') {
          onHistoryClick(e, { uploadKey });
        }
      },
      [onHistoryClick, uploadKey]
    );

    const handleTextClick = useCallback(e => {
      if (e.target.tagName !== 'SPAN') {
        e.stopPropagation();
      }
    }, []);

    const handleRemove = useCallback(
      e => {
        e.stopPropagation();
        // 取消正在进行的上传
        if (xhrRef.current) {
          if (typeof xhrRef.current.cancel === 'function') {
            // Axios取消上传
            xhrRef.current.cancel('上传已取消');
          }
          xhrRef.current = null;
        }

        // 清除进度更新定时器
        if (progressUpdateRef.current) {
          clearInterval(progressUpdateRef.current);
          progressUpdateRef.current = null;
        }

        // 重置上传状态
        setUploading(false);
        isUploadingRef.current = false;
        // 保留进度条显示，添加延迟重置进度，以提供更好的用户体验
        setTimeout(() => {
          setUploadProgress(0);
          setError('');
          setCurrentUploadFileName('');
        }, 300);
        if (typeof onAudioRemove === 'function') {
          onAudioRemove(uploadKey);
        }
      },
      [onAudioRemove, uploadKey]
    );

    // 组件卸载时清理定时器
    useEffect(() => {
      return () => {
        if (progressUpdateRef.current) {
          clearInterval(progressUpdateRef.current);
        }
      };
    }, []);

    useImperativeHandle(ref, () => ({
      handleCustomRequest,
    }));

    return (
      <div className={styles.audioUploadWrapper}>
        {(uploading || isUploadingRef.current || currentUploadFileName) && uploadProgress < 100 && (
          <div className={styles.uploadProgressContainer}>
            <div className={styles.uploadProgress}>
              <div className={styles.uploadingText}>
                <span>{currentUploadFileName || audioObj[audioKey]?.name || '正在上传...'}</span>
                <div className={styles.progressText}>{Math.round(uploadProgress)}%</div>
              </div>
              <div className={styles.progressBar}>
                <div
                  className={styles.progressFill}
                  style={{
                    width: `${uploadProgress}%`,
                    transition: uploading ? 'width 0.3s ease' : 'none',
                  }}></div>
              </div>
            </div>
            <div className={styles.deleteIcon} onClick={handleRemove}>
              <Image src={ICON_PATHS.X_DELETE_ICON} draggable={false} preview={false}></Image>
            </div>
          </div>
        )}

        {error && <div className={styles.errorText}>{error}</div>}

        <Upload
          {...uploadConfig}
          className={uploadClassName}
          customRequest={handleCustomRequest}
          // onProgress={({ percent }) => setUploadProgress(percent)}
          loading={uploading}>
          {
            <div className={styles.uploadPlaceholder}>
              <div className={styles.uploadIcon}>
                <Image src={ICON_PATHS.AUDIO_UPLOAD_ICON} draggable={false} preview={false}></Image>
              </div>

              <div className={styles.uploadText} onClick={handleTextClick}>
                <span>{title}</span>
                {subtitle && <span>({subtitle})</span>}
              </div>

              {/* {onHistoryClick && (
              <div className={styles.uploadText}>
                从<span onClick={handleHistoryClickWrapper}>「历史文件」</span>上传
              </div>
            )} */}
            </div>
          }
        </Upload>
      </div>
    );
  }
);

export default AudioUploadComponent;